package com.smt.modules.app.controller;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.smt.common.enums.Code;
import com.smt.common.utils.*;
import com.smt.modules.app.annotation.BillAndGrade;
import com.smt.modules.app.annotation.Login;
import com.smt.modules.app.annotation.LoginUser;
import com.smt.modules.bus.entity.*;
import com.smt.modules.bus.service.AddressBookService;
import com.smt.modules.bus.service.InviteService;
import com.smt.modules.bus.service.ProjectService;
import com.smt.modules.bus.service.TeamService;
import com.smt.modules.bus.vo.request.JoinInvitesReq;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 邀请表
 *
 * @author zhangyi
 * @date 2018/10/11 16:17
 */
@RestController
@RequestMapping("/app/invite")
@Api(tags = {"AppInviteController"},description = "邀请表(客户端接口)")
public class AppInviteController {

    @Autowired
    private InviteService inviteService;

    @Autowired
    private TeamService teamService;

    @Autowired
    private ProjectService projectService;
    @Resource
    private AddressBookService addressBookService;
    /**
     * 发送邀请
     *
     * @param projectId
     * @param contact
     * @param type
     * @return
     */
    @Login
    @PostMapping("/send/{type}/{userType}/{projectId}")
    @ApiOperation(value = "type(0内部1外部)userType(手机号/邮箱)",notes = "发送邀请",httpMethod = "POST")
    @BillAndGrade(value = Constant.TASK_7)
    public R sendInvite(@PathVariable("type") @NotNull(message = "方式不能为空") Integer type,
                        @PathVariable("userType") @NotEmpty(message = "联系方式不能为空") String contact,
                        @PathVariable("projectId") @NotEmpty(message = "项目id不能为空") Long projectId,
                        @LoginUser MemberUserEntity memberUserEntity){
        R result = null;

        Long teamId = getTeamId(projectId);
        if(teamId.equals(0)){
            return R.error(1,"获取团队实体错误，无法通过当前项目获取到团队实体");
        }
        result = inviteStatus(memberUserEntity,teamId,contact,type);
        if(Objects.isNull(result)){
            return inviteService.sendInvite(type,contact,memberUserEntity,projectId,teamId);
        }else{
            return result;
        }
    }

    /**
     * 查看用户邀请记录
     *
     * @param contact
     * @param memberUserEntity
     * @return
     */
    @Login
    @GetMapping("/getInvitationStatus/{projectId}/{contact}")
    @ApiOperation(value = "查看用户邀请记录",httpMethod = "GET")
    public R getInvitationStatus(@PathVariable("contact") String contact,
                              @LoginUser MemberUserEntity memberUserEntity,
                              @PathVariable("projectId") Long projectId){
        Long teamId = getTeamId(projectId);
        String fromUser = memberUserEntity.getMobile() == null ?
                memberUserEntity.getEmail() : memberUserEntity.getMobile();
        InviteEntity inviteEntity = inviteService.selectOne(new EntityWrapper<InviteEntity>()
                .eq("to_user", contact)
                .eq("from_user", fromUser)
                .eq("team_id", teamId));
        if(null == inviteEntity){
            return R.ok("该用户未没邀请过");
        }else {
            return R.ok("该用户邀请记录").put("invite",inviteEntity);
        }
    }
    /**
     * 拒绝邀请后的操作
     *
     * @param contact
     * @param memberUserEntity
     * @return
     */
    @Login
    @PostMapping("/secondInvitation/{projectId}/{contact}/{type}")
    @ApiOperation(value = "type(0拒绝重新邀请 1继续重新邀请)",httpMethod = "POST")
    public R secondInvitation(@PathVariable("contact") String contact,
                                    @LoginUser MemberUserEntity memberUserEntity,
                                    @PathVariable("projectId") Long projectId,
                                    @PathVariable("type") @Min(0) @Max(1) Integer type){
        Long teamId = getTeamId(projectId);
        if(teamId.equals(0)){
            return R.error(1,"无法获取当前项目的团队");
        }
        String fromUser = memberUserEntity.getMobile() == null ?
                memberUserEntity.getEmail() : memberUserEntity.getMobile();
        InviteEntity inviteEntity = inviteService.selectOne(new EntityWrapper<InviteEntity>()
                .eq("to_user", contact)
                .eq("from_user", fromUser)
                .eq("team_id", teamId)
                .eq("is_operate", 2));
        boolean flag = false;
            if (inviteEntity != null && type.equals(1)) {
                Long id = inviteEntity.getId();
                flag = inviteService.deleteById(id);
            }
        if(flag){
            inviteService.sendInvite(0,contact,memberUserEntity,projectId,teamId);
            return R.ok("重新邀请用户成功！");
        }else{
            return R.ok("取消重新邀请");
        }
    }


    /**
     * 点击邀请连接 1 确认 2 拒绝
     *
     * @param contact
     * @return
     */
    @GetMapping("/enter/{contact}/{type}/{formUser}/{teamId}")
    @ApiOperation(value = "确认邀请,加入该项目，如果没有账号需要先注册再连接，有的话直接将其关系连接到项目里面",httpMethod = "GET",hidden = true)
    public R enterInvite(@PathVariable(value = "contact") String contact,
                         @PathVariable("type") @Min(0) @Max(2) Integer type,
                         @PathVariable("formUser") String formUser,
                         @PathVariable("teamId") @NotNull(message = "邀请人所在退队id不能为空") Long teamId){

//        return inviteService.enterInvite(contact,type,formUser,teamId);
        return null;
    }

    /**
     * 点击邀请列表连接 1 确认 2 拒绝
     *
     * @param joinInvites
     * @return
     */
    @PostMapping("/enterList")
    @ApiOperation(value = "点击邀请列表连接",httpMethod = "POST")
    public R enterList(@RequestBody List<JoinInvitesReq> joinInvites){
        List<R> resultList = new ArrayList<>();
        joinInvites.stream().forEach(j -> {
            R result = new R();
            Integer type = j.getType();
            switch (type){
                case 0:
                case 1:
                case 2:
                    R r = inviteService.enterInviteList(j);
                    result.put("code", "200").put("result",r);
                    break;
                    default:
                        result.put("code","444").put("msg","您输入的账号错误");
                        break;
            }
            resultList.add(result);
        });
        return R.ok("登录成功").put("msg",resultList);
    }

    /**
     * 检测用户是否被邀请过
     *
     * @param contact
     * @return
     */
    @GetMapping("/haveInvite/{contact}")
    @ApiOperation(value = "检测用户是否被邀请过",httpMethod = "GET")
    public R haveInvite(@PathVariable(value = "contact") String contact){
        Wrapper<InviteEntity> eq = isContact(contact,"is_operate");
        if(Objects.isNull(eq)){
            return R.error(EnumToKeyUtil.toInt(Code.MODIFY_DATA_ERROR),"您输入的联系方式错误！");
        }
        InviteEntity inviteE = inviteService.selectOne(eq);

        if (inviteE == null){
            return R.ok()
                    .put("msg","该用户未被邀请过，直接登录")
                    .put("code",1);
        }
        Integer isOperate = inviteE.getIsOperate();
        if(isOperate.equals(0)){
            return R.ok()
                    .put("msg","该用户被邀请过，但是未操作邀请")
                    .put("code",2);
        }else if(isOperate.equals(1)){
            return R.ok().put("msg","该用户被邀请过，确认了操作邀请，直接登录")
                    .put("code",3);
        }else {
            return R.ok()
                    .put("msg","该用户被邀请过，拒绝邀请")
                    .put("code",4);
        }
    }

    /**
     * 查看用户是否有多次被邀请
     *
     * @param contact
     * @return
     */
    @GetMapping("/inviteList/{contact}")
    @ApiOperation(value = "查看用户是否有多次被邀请,并且用户无操作 返回邀请列表（用户邮箱）",httpMethod = "GET")
    public R inviteList(@PathVariable(value = "contact") String contact){
        Wrapper<InviteEntity> isOperate = isContact(contact,"is_operate");
        if(Objects.isNull(isOperate)){
            return R.error(EnumToKeyUtil.toInt(Code.MODIFY_DATA_ERROR),"您输入的联系方式错误！");
        }
        List<InviteEntity> inviteList = inviteService.selectList(isOperate);
        CopyOnWriteArrayList<InviteEntity> copyOnWriteArrayList = new CopyOnWriteArrayList<>(inviteList);
        copyOnWriteArrayList.stream().forEach(i -> {
            Long teamId = i.getTeamId();
            TeamEntity teamEntity = teamService.selectById(teamId);
            if(!Objects.isNull(teamEntity)){
                Long projectId = teamEntity.getProjectId();
                ProjectEntity projectEntity =
                        projectService.selectById(projectId);
                if(!Objects.isNull(projectEntity)) {
                    i.setProjectName(projectEntity.getProjectName());
                }
                if(projectId.equals(new Long(0))){
                    copyOnWriteArrayList.remove(i);
                }
            }
        });
        if(copyOnWriteArrayList != null && copyOnWriteArrayList.size() != 0){
            return R.ok("公司邀请列表").put("inviteList",copyOnWriteArrayList).put("code",1);
        }else{
            return R.ok("该用户未被邀请过").put("code",0);
        }
    }




    /**
     * 批量邀请用户
     *
     * @param ids
     * @return
     */
    @Login
    @PostMapping("/batchInvites/{projectId}")
    @ApiOperation(value = "批量邀请用户",httpMethod = "POST")
    public R batchInvites(@PathVariable("projectId") Long projectId,
                          @RequestParam("ids") String ids,
                          @LoginUser MemberUserEntity memberUserEntity){
        StringToListUtil stringToListUtil = new StringToListUtil();
        List<Long> idsList = stringToListUtil.encode(Long.class, ids);
        List<R> rList = new ArrayList<>();
        Long teamId = getTeamId(projectId);
        for(Long id : idsList){
            AddressBookEntity addressBookEntity = addressBookService.selectById(id);
            String emailContact = addressBookEntity.getEmailContact();
            R result = inviteStatus(memberUserEntity, teamId, emailContact, 0);
            if(Objects.isNull(result)){
                result = inviteService.sendInvite(0,emailContact,memberUserEntity,projectId,teamId);
            }
            rList.add(result);
        }
        return R.ok().put("rList",rList);
    }



    /**
     *  获取邀请记录成员集合
     *
     * @return
     */
    @Login
    @GetMapping("/addressBooks/{projectId}")
    @ApiOperation(value = "获取邀请记录成员集合",httpMethod = "GET")
    public R addressBooks(@PathVariable("projectId") Long projectId,
                          @LoginUser MemberUserEntity memberUserEntity){
        Long userId = memberUserEntity.getUserId();
        Long teamId = getTeamId(projectId);
        if(teamId.equals(0)){
            return R.error(1,"获取团队实体错误，无法通过当前项目获取到团队实体");
        }
        String fromUser = memberUserEntity.getMobile() == null ?
                memberUserEntity.getEmail() : memberUserEntity.getMobile();
        List<AddressBookEntity> addressBookEntities = addressBookService.selectList(new EntityWrapper<AddressBookEntity>()
                .eq("is_delete", 0)
                .eq("member_id", userId));
        for(int i = 0; i < addressBookEntities.size(); i++){
            AddressBookEntity addressBookEntity = addressBookEntities.get(i);
            //查询用户邀请记录中是否存在
            InviteEntity invite = inviteService.selectOne(new EntityWrapper<InviteEntity>()
                    .eq("team_id", teamId)
                    .eq("to_user", addressBookEntity.getEmailContact())
                    .eq("from_user", fromUser));
            if(!Objects.isNull(invite)) {
                addressBookEntity.setStatus(invite.getIsOperate());
            }
        }
        PageUtils pageUtils = new PageUtils(addressBookEntities,addressBookEntities.size(),10,1);
        return R.ok().put("addressBookes",pageUtils);
    }
    /**
     *  删除邀请记录
     *
     * @return
     */
    @Login
    @DeleteMapping("/deleteAddressBook")
    @ApiOperation(value = "删除邀请记录",httpMethod = "DELETE")
    public R deleteAddressBook(@RequestParam("ids") String ids){
        StringToListUtil<Long> stringToListUtil = new StringToListUtil<>();
        List<Long> encode = stringToListUtil.encode(Long.class, ids);
        List<AddressBookEntity> addressBookEntityList = new ArrayList<>();
        for(Long id : encode) {
            AddressBookEntity addressBookEntity = new AddressBookEntity(id, 1);
            addressBookEntityList.add(addressBookEntity);
        }
        boolean b = addressBookService.updateBatchById(addressBookEntityList);
        return b?R.ok("删除成功"):R.error(EnumToKeyUtil.toInt(Code.DELETE_DATA_ERROR),"删除数据失败");
    }




    /**
     * 根据项目获取其对应的团队id
     *
     * @param projectId
     * @return
     */
    private Long getTeamId(Long projectId){
        //查找当前项目下的团队列表
        List<TeamEntity> projectIds = teamService.selectList(new EntityWrapper<TeamEntity>()
                .eq("project_id", projectId));
        TeamEntity teamEntity = new TeamEntity();
        projectIds.stream().forEach(l -> {
            //确定当前项目的所属团队 根据其 创建者=成员 确定
            if (l.getMemberId().equals(l.getCreateorId())) {
                teamEntity.setId(l.getId());
            }
        });
        //获取到当前团队实体
        if (Objects.isNull(teamEntity.getId())) {
            return new Long(0);
        }
        return teamEntity.getId();
    }

    /**
     * 通过验证用户的输入的联系方式，查找用户是否是手机邀请还是邮箱邀请
     *
     * @param sqlStr
     * @param contact
     * @return
     */
    private Wrapper<InviteEntity> isContact(String contact,String sqlStr){
        Wrapper<InviteEntity> teamEntityEntityWrapper = new EntityWrapper<InviteEntity>()
                .eq(sqlStr, 0);
        boolean isPhone = CheckUtil.checkPhone(contact);
        boolean isEmail = CheckUtil.checkEmail(contact);
        if(isPhone){
            teamEntityEntityWrapper.eq("to_user_contact", contact);
        }else if(isEmail){
            teamEntityEntityWrapper.eq("to_user", contact);
        }else{
            return null;
        }
        return teamEntityEntityWrapper;
    }

    /**
     * 判断用户邀请状态
     *
     * @param memberUserEntity
     * @param teamId
     * @param contact
     * @param type
     * @return
     */
    public R inviteStatus(MemberUserEntity memberUserEntity,Long teamId,String contact,Integer type){
        String fromUser = memberUserEntity.getMobile() == null ?
                memberUserEntity.getEmail() : memberUserEntity.getMobile();
        //查询用户邀请记录中是否存在
        InviteEntity inviteEntities = inviteService.selectOne(new EntityWrapper<InviteEntity>()
                .eq("team_id", teamId)
                .eq("to_user", contact)
                .eq("from_user", fromUser));
        if(null != inviteEntities && type.equals(0)){
            Integer isOperate = inviteEntities.getIsOperate();
            switch (isOperate){
                case 0:
                    return R.error("该用户已被邀请,等待确认中...").put("code",980);
                case 1:
                    return R.error("该用户确认了邀请，不可重复邀请").put("code",980);
                case 2:
                    return R.error("该用户已经拒绝您的邀请").put("code",989);
                default:
                    break;
            }
        }
        return null;
    }
}